Plain constructor injection works when the token is a class — TypeScript emits the type automatically. @Inject(TOKEN) is required when the token is a string, symbol, or InjectionToken because those have no TypeScript type that reflect-metadata can read.
Class tokens — use plain constructor injection.
String tokens — always use @Inject('TOKEN_NAME').
Symbol tokens — always use @Inject(SYMBOL).
InjectionToken — use @Inject(TOKEN) for type-safe non-class tokens.
Prefer InjectionToken over raw strings to avoid typos and get TypeScript type checking.